Задачи по строкам. Уровень 2

Задача 1. Отрезки строки:

Буквы br считаются разделительными символами, которые делят строку на два отрезка. Количество br неограниченно, то есть количество отрезков будет равно количеству br + 1. Необходимо вывести самый большой отрезок, если таких отрезков несколько, то выведите любой из них. Гарантируется, что в строке есть как минимум две части, разделенные символами br.
Входные данные:
Единственная строка содержит строку от 3 до 10^4 символов.
Выходные данные:
Выведите самую большую часть исходной строки.

Пример:

Ввод Вывод
S28brkRFdbr6m kRFd
4vbrt 4v

Пояснение к примеру 1

Существуют три отрезка:
отрезок S28 длины 3;
отрезок kRFd длины 4;
отрезок 6m длины 2.
Естественно отрезок kRFd является самым большим.

Задача 2. Делимость:

Кирилл любит проверять делимость чисел на 3 и на 8. Но чисел может быть слишком много, поэтому он просит вас помочь ему.
Входные данные:
Первая строка содержит одно целое число t (1 ≤ t ≤ 100) - количество чисел.
В следующих t строках записаны числа ai (1 ≤ ai ≤ 10^30).
Выходные данные:
Выведите для каждого числа yes, если оно делится на 3 и на 8, иначе no.

Пример:

Ввод Вывод
1
24
yes
2
2268
72
no
yes

Максимальное число, которое вмещается в long long int намного меньше чем максимальное число по условию. Поэтому для записи такого числа мы используем строку.
Для решения нам нужно вспомнить признак делимости на 3 и на 8.
Алгоритмы описаны в примере.

Пример на Си:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
	int n, i, t, sum, num;
	char S[100][30];
	scanf("%i", &t);
	getchar();
	for (i = 0; i < t; i++) {
		gets(S[i]);
	}
	for (int j = 0; j < t; j++) {
		n = strlen(S[j]);
		if (n < 3) {  // мы можем обычным способом проверить делимость
			num = 0;
			for (i = 0; i < n; i++) {  // алгоритм преобразования
				num *= 10;
				num = num + (S[j][i] - 48);  // строки цифр в число
			}
			if (num % 3 == 0 && num % 8 == 0) {  // проверка на делимость
				printf("yes\n");
			}
			else {
				printf("no\n");
			}
		}
		else {
			sum = 0;
			num = 0;
			for (i = 0; i < n; i++) {  // подсчет суммы цифр
				sum = sum + (S[j][i] - 48);
			}
			for (i = n - 3; i < n; i++) {  // алгоритм преобразования трех
				num *= 10;
				num = num + (S[j][i] - 48);  // последних цифр строки в число
			}
			if (sum % 3 == 0 && num % 8 == 0) {  // проверка на делимость
				printf("yes\n");
			}
			else {
				printf("no\n");
			}
		}
	}
	return 0;
}

Задача 3.1. Численность животных:

Группа ученых отправилась в заповедник для измерения численности животных. Когда ученые встречали животного, то записывали в компьютер через пробел его тип питания (если хищник, то predator, если травоядный, то herbivore) и его название. От вас требуют, по данным ученых, определить кто из хищников встречался больше всего раз, а из травоядных меньше всего. Если ответов несколько, то вывести любой из них.
Входные данные:
Первая строка содержит одно целое число t (2 ≤ t ≤ 100) - количество встреч.
В следующих t строках записаны тип питания и название животного. Количество символов в строке от 12 до 30
Выходные данные:
В первой строке выведите название хищника, который встречается больше всего раз и количество таких животных.
Во второй строке выведите название травоядного, который встречается меньше всего раз и количество таких животных.

Пример:

Ввод Вывод
8
predator leopard
herbivore gazelle
predator lion
predator lion
herbivore gazelle
herbivore antelope
predator leopard
predator lion
lion 3
antelope 1

Задача 3.2. Численность животных:

...
От вас снова требуют обработать данные ученых, но на этот раз все сложнее. Вам нужно отсортировать хищников по неубыванию, а травоядных по невозрастанию. Отсортировывать нужно естественно по количеству встреч.
Входные данные:
Первая строка содержит одно целое число t (2 ≤ t ≤ 100) - количество встреч.
В следующих t строках записаны тип питания и название животного. Количество символов в строке от 10 до 30
Выходные данные:
Выведите слово predators, и далее в каждой строке выведите названия животных и количество встреч по неубыванию.
Выведите слово herbivores, и далее в каждой строке выведите названия животных и количество встреч по неубыванию.

Пример:

Ввод Вывод
8
predator leopard
herbivore gazelle
predator lion
predator lion
herbivore gazelle
herbivore antelope
predator leopard
predator lion
predators
lion 3
leopard 2
herbivores
antelope 1
gazelle 2

Задача 4. Большие числа:

Даня любит большие числа, поэтому он в каждом тексте ищет самое большое число и записывает его в тетрадь. Но сегодня у него слишком много текстов, помогите Дане найти самые большие числа в каждом тексте. Гарантируется, что хотя бы одно число в каждом тексте есть.
Входные данные:
Первая строка содержит одно целое число t (1 ≤ t ≤ 100) - количество текстов.
В следующих t строках записаны строки от 1 до 50 символов.
Выходные данные:
Выведите для каждой строки максимальное число в ней.

Пример:

Ввод Вывод
4
Rdf432g64f
s6PO57
t4j12fraew6e
1233g3ew
432
57
12
1233

Допустим есть две строки a и b, а число, полученное из строки a, будет равно A, а из строки b будет равно B. Можно обе строки перевести в числа и сравнить их. Есть и другой способ. Если длина строки a > b, то и число A > B и наоборот. Если обе строки равны по длине, то сравниваем их лексиграфически с помощью функции strcmp().


Задача 5. Сокращение текста:

У Влада есть большой текст. Текст слишком велик, поэтому он хочет сократить его следующим образом: если есть последовательность повторяющихся символов, то нужно вместо этой последовательностью вставить количество элементов в этой последовательности и сам элемент. Пример: Дана строка SGAAAARet, после сокращения строка будет выглядеть вот так: SG4ARet. У Влада мало времени, поэтому он просит вас написать алгоритм по сокращению текста.
Входные данные:
Единственная строка содержит строку от 1 до 10^4 символов.
Выходные данные:
Выведите сокращенную строку.

Пример:

Ввод Вывод
fEEEjhhr f3Ej2hr
rrrrrwedDdddssss 5rwedD3d4s

Пример на Си:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
	char S[10000];
	int i, l, j;
	gets(S);
	l = strlen(S);
	i = 0;
	while (i < l) {
		j = i;
		while (j + 1 < l && S[j] == S[j + 1]) {
			j++;
		}
		if (i != j) {
			printf("%i%c", j - i + 1, S[j]);
		}
		else {
			printf("%c", S[j]);
		}
		i = j + 1;
	}
	return 0;
}

Задача 6. Что больше:

Вам дана строка. Выведите yes, если произведение всех отдельно стоящих цифр больше чем самое большое число в этом тексте, иначе no. Отдельно стоящей цифрой называется цифра, у которой все соседи не цифры. Гарантируется, что самое большое число и произведение отдельно стоящих цифр меньше 10^18.
Входные данные:
Единственная строка содержит строку от 3 до 10^4 символов.
Выходные данные:
Выведите ответ на задачу.

Пример:

Ввод Вывод
S8R32P3k2 yes

Пояснениек примеру

8 * 3 * 2 > 32, поэтому yes

Задача 7. Турнир по футболу:

В городе F весь месяц шел турнир по футболу между N командами. Всего было сыграно M матчей. За каждую победу команде прибавлялось 3 очка, за каждую ничью 1 очко, за каждое поражение 0 очков. Вам поручено составить итоговую таблицу по результатам матчей. Гарантируется, что количество очков в сумме для каждой команды точно меньше 10^9.
Входные данные:
Первая строка содержит два целых числа N (1 ≤ N ≤ 20) и M (1 ≤ M ≤ 100) - количество команд и матчей соответственно.
Далее идут N строк - названия команд. Гарантируется, что название команды меньше 10 символов и не разделено пробелами.
Далее идут M пар строк, описывающих матч. Каждая пара содержит две строки:
1)Первая строка содержит название двух команд через тире.
2)Во второй строке через двоеточие записаны количество голов команд соответственно. Гарантируется, что числа меньше 1000.
Выходные данные:
Выведите итоговую таблицу по неубыванию. Каждая строка должна содержать название команды и через пробел количество очков.

Пример:

Ввод Вывод
5 10
PSG
ARSENAL
JUVENTUS
CHELSEA
BARCELONA
PSG-CHELSEA
2:3
ARSENAL-BARCELONA
7:12
CHELSEA-BARCELONA
4:3
JUVENTUS-CHELSEA
2:0
PSG-ARSENAL
4:1
PSG-BARCELONA
2:3
JUVENTUS-BARCELONA
4:5
JUVENTUS-PSG
7:3
ARSENAL-JUVENTUS
4:2
CHELSEA-ARSENAL
2:2
BARCELONA 9
CHELSEA 7
JUVENTUS 6
ARSENAL 4
PSG 3

Создаем массив структур, в котором будут храниться названия команд и их очки в турнире. Заполняем этот массив при вводе названий команд. Изначально сумма очков каждой команды равны 0. При вводе данных о матчах, мы в строку str1 записываем название первой команды и вручную добавляем в конец этой строки символ '\0', чтобы можно было использовать функцию сравнения строк strcmp() в дальнейшем. Такие же действия выполняем с названием второй команды и записываем ее в строку str2. Далее обрабатываем счет. Первое количество голов записываем в переменную num1, а второе количество в num2. Далее сравниваем num1 и num2 и выполняем поиск нужных команд с помощью функции strcmp() и прибавляем нужное количество очков команде или командам. В конце программы сортируем массив структур по количеству очков и выводим результат.

Пример на Си:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
struct football {
	char name[10];
	int total;  // всего очков
};
 
int sort(const void* a, const void* b) {
	struct football x = *(struct football*)(a);
	struct football y = *(struct football*)(b);
	return y.total - x.total;
}
 
int main() {
	int N, M, i, j, l, num1, num2;
	char string1[20], string2[20];
	char str1[10], str2[10];
	struct football A[100];
	scanf("%i%i", &N, &M);
	for (i = 0; i < N; i++) {
		scanf("%s", &A[i].name);
		A[i].total = 0;
	}
 
	for (i = 0; i < M; i++) {
		scanf("%s%s", &string1, &string2);
		// отделяем первое название от второго
		j = 0;
		while (string1[j] != '-') {
			str1[j] = string1[j];
			j++;
		}
		str1[j] = '\0';  // вручную добавляем симвлол конца строки
		j++;
		l = 0;
		while (string1[j] != '\0') {
			str2[l] = string1[j];
			j++;
			l++;
		}
		str2[l] = '\0';  // вручную добавляем симвлол конца строки
 
		num1 = 0;  // первое количество голов
		j = 0;
		while (string2[j] != ':') {
			num1 = num1 * 10 + (string2[j] - 48);
			j++;
		}
		j++;
		num2 = 0;  // второе количество голов
		while (string2[j] != '\0') {
			num2 = num2 * 10 + (string2[j] - 48);
			j++;
		}
 
		if (num1 > num2) {  // победил первая команда
			for (j = 0; j < N; j++) {
				if (strcmp(str1, A[j].name) == 0) { 
					A[j].total += 3;
					break;
				}
			}
			continue;
		}
		if (num1 < num2) {  // победил вторая команда
			for (j = 0; j < N; j++) {
				if (strcmp(str2, A[j].name) == 0) {
					A[j].total += 3;
					break;
				}
			}
		}
		if (num1 == num2) {  // ничья
			for (j = 0; j < N; j++) {
				if (strcmp(str1, A[j].name) == 0) {
					A[j].total += 1;
					break;
				}
			}
			for (j = 0; j < N; j++) {
				if (strcmp(str2, A[j].name) == 0) {
					A[j].total += 1;
					break;
				}
			}
		}
	}
	qsort(A, N, sizeof(struct football), sort);
	for (i = 0; i < N; i++) {
		printf("%s %i\n", A[i].name, A[i].total);
	}
	return 0;
}

Задача 8. Калькулятор:

У Пети сломался калькулятор и он просит вас написать ему алгоритм для некоторых функций калькулятора. Пети нужно, чтобы калькулятор мог выполнять следующие действия: умножать(*), делить(/), складывать(+), вычитать(-) и возводить в любую целую положительную степень(^). Таких действий может быть несколько, но минимум одно. Гарантируется, что все вычисления по модулю меньше 10^9, все вводимые числа целые, деление на 0 отсутствует, скобок и пробелов нет.
Входные данные:
Единственная строка содержит строку от 3 до 40 символов.
Выходные данные:
Выведите ответ. Возможна погрешность.

Пример:

Ввод Вывод
6+8*3-27 3
6*4-2^2+400 420

Создадим массив numb для храниия чисел и массив act для хранения дейсвий над числами. Можно заметить, что дейсвие act[i] будет выполняться для чисел numb[i] и numb[i + 1]. Результат будем сохранять в элемент numb[i]. После этого нужно удалить из массива элемент numb[i + 1], поэтому сдвигаем массив на один элемент влево от индекса i + 1. Далее нужно удалить само действие(массив act), начинать сдвиг нужно от индекса i. Сначало выполняем поочередно все дейсвия со степенью, потом с умножением и делением, потом с сложением и вычитанием. По итогу ответ будет записан в numb[0].

тест: 35+84*5^3-648+8/2

Пример на Си:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main() {
	char S[40], act[20];
	int i, j, n;
	float numb[20];
	int numb_n = 0, act_n = 0;  // количество элементов массивов
	gets(S);
	i = 0;
	while (S[i] != '\0') {  // заполнение двух массивов
		n = 0;
		while (S[i] <= '9' && S[i] >= '0' && S[i] != '\0') {
			n = n * 10 + (S[i] - 48);
			i++;
		}
		numb[numb_n++] = n;
		if (S[i] == '\0') break;
		act[act_n++] = S[i];
		i++;
	}
	for (i = 0; i < act_n; i++) {   // действия со степенью
		if (act[i] == '^') {
			n = numb[i];
			for (j = 0; j < numb[i + 1] - 1; j++) {
				numb[i] = numb[i] * n;
			}
			for (j = i; j < act_n - 1; j++) {
				act[j] = act[j + 1];
			}
			for (j = i + 1; j < numb_n - 1; j++) {
				numb[j] = numb[j + 1];
			}
			act_n--;
			numb_n--;
			i--;
		}
	}
	for (i = 0; i < act_n; i++) {  // действия с умножениием и делением
		if (act[i] == '*' || act[i] == '/') {
			if (act[i] == '*') {
				numb[i] = numb[i] * numb[i + 1];
			}
			else{
				numb[i] = numb[i] / numb[i + 1];
			}
			for (j = i; j < act_n - 1; j++) {
				act[j] = act[j + 1];
			}
			for (j = i + 1; j < numb_n - 1; j++) {
				numb[j] = numb[j + 1];
			}
			act_n--;
			numb_n--;
			i--;
		}	
	}
	for (i = 0; i < act_n; i++) {  // на этом этапе в массиве act остались только '+' и '-'
		if (act[i] == '+') {
			numb[i] = numb[i] + numb[i + 1];
		}
		else {
			numb[i] = numb[i] - numb[i + 1];
		}
		for (j = i; j < act_n - 1; j++) {
			act[j] = act[j + 1];
		}
		for (j = i + 1; j < numb_n - 1; j++) {
			numb[j] = numb[j + 1];
		}
		act_n--;
		numb_n--;
		i--;
	}
	printf("%lg", numb[0]);
	return 0;
}

Code.C © Copyright Павел Калашников 2021
обратная связь code.c04@mail.ru